package com.yangle.frame.common.utils;

import com.yangle.frame.common.entity.Column;
import com.yangle.frame.common.entity.PackageInfo;
import com.yangle.frame.common.entity.Table;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;

import java.io.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GenerateCodingUtil {
    public static boolean generate(Map<String,String> map) throws IOException {


        String root_path = map.get("root_path");
        String generate_path = map.get("generate_path");
        String templatePath = root_path + File.separator + "src"+File.separator+"main"+File.separator+"resources"  + File.separator + "template";
        /* 创建一个合适的configuration */
        Configuration cfg = new Configuration();

        // 设置模板加载的方式
        cfg.setDirectoryForTemplateLoading(new File(templatePath));

        cfg.setObjectWrapper(new DefaultObjectWrapper());
        cfg.setDefaultEncoding("UTF-8");

        PackageInfo packageInfo = new PackageInfo();
        Table table = generateTable(map.get("table_name"));
        table.setTableZhName(map.get("table_zh_name"));
        packageInfo.setTable(table);

        packageInfo.setClassName(convertTableToClass(map.get("table_name")));

        packageInfo.setPackageName(map.get("package_name"));//前面包名写死
        packageInfo.setClassName(convertTableToClass(map.get("table_name")));
        packageInfo.setModelName(map.get("model_name"));
        packageInfo.setAuthor(map.get("author"));
        String scope = map.get("scope")==null?"all":map.get("scope");//默认mvc层都生成
        String[] infos = null;
        switch (scope.toLowerCase()) {
            case "all":
                infos = new String[]{"dao", "entity", "service",  "mapper","controller","edit","list","view"};
                break;
            case "dao":
                infos = new String[]{"dao"};
                break;
            case "entity":
                infos = new String[]{"entity"};
                break;
            case "service":
                infos = new String[]{"service"};
                break;

            case "mapper":
                infos = new String[]{"mapper"};
                break;
            case "controller":
                infos = new String[]{"controller"};
                break;
            case "edit":
                infos = new String[]{"edit"};
                break;
        case "list":
                infos = new String[]{"list"};
                break;
            case "view":
                infos = new String[]{"view"};
                break;
        }

        generate_path = generate_path + File.separator + "src" + File.separator + "main";
        List<String> paths = new ArrayList<>();
        for (String info : infos) {
            String path = "";
            if (info.equals("mapper")) {
                path = generate_path + File.separator + "resources" + File.separator +"mapper"+ File.separator + packageInfo.getModelName()+File.separator+packageInfo.getClassName().toLowerCase();
                paths.add(path + File.separator + packageInfo.getClassName() + "Mapper.xml");
            } else if (info.equals("dao")) {
                path = generate_path + File.separator + "java" + File.separator + packageInfo.getPackageName().replace(".", File.separator) + File.separator + "mapper";
                paths.add(path + File.separator + packageInfo.getClassName() + "Mapper.java");
            } else if (info.equals("entity")) {
                path = generate_path + File.separator + "java" + File.separator + packageInfo.getPackageName().replace(".", File.separator) + File.separator + info;
                paths.add(path + File.separator + packageInfo.getClassName() + ".java");
            } else if (info.equals("service")) {
                path = generate_path + File.separator + "java" + File.separator + packageInfo.getPackageName().replace(".", File.separator) + File.separator + info;
                paths.add(path + File.separator + packageInfo.getClassName() + "Service.java");
            }else if (info.equals("controller")) {
                path = generate_path + File.separator + "java" + File.separator + packageInfo.getPackageName().replace(".", File.separator) + File.separator + info;
                paths.add(path + File.separator + packageInfo.getClassName() + "Controller.java");
            }else if (info.equals("list")) {
                path = generate_path + File.separator + "resources" + File.separator + "templates" + File.separator  +packageInfo.getModelName()+File.separator+packageInfo.getClassName().toLowerCase();
                paths.add(path + File.separator +"list.html");
            }else if (info.equals("edit")) {
                path = generate_path + File.separator + "resources" + File.separator + "templates" +  File.separator +packageInfo.getModelName()+File.separator+packageInfo.getClassName().toLowerCase();
                paths.add(path + File.separator +"edit.html");
            }else if (info.equals("view")) {
                path = generate_path + File.separator + "resources" + File.separator + "templates" +  File.separator +packageInfo.getModelName()+File.separator+packageInfo.getClassName().toLowerCase();
                paths.add(path + File.separator +"view.html");
            }
            createDir(path);
        }
        Map root = new HashMap();
        root.put("packageInfo", packageInfo);
        try{
        for (int i = 0; i < infos.length; i++) {
            String info = infos[i];
            Template temp = cfg.getTemplate(info + ".ftl");
            temp.setEncoding("UTF-8");
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(paths.get(i))),"UTF-8"));
            temp.process(root, bufferedWriter);
            bufferedWriter.flush();
        }}catch (Exception e){
            e.printStackTrace();
            return false;
        }
return true;
    }

    private static void createDir(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
    }


    private static String convertTableToClass(String content) {
        String name = "";
        if (content.contains("_")) {
            //前后拼接
            String[] names = content.split("_");
            for (int i = 0; i < names.length; i++) {
                String tempName = names[i];
                tempName = tempName.substring(0, 1).toUpperCase() + tempName.substring(1);
                name += tempName;

            }
        } else {
            name = content.substring(0, 1).toUpperCase() + content.substring(1);
        }
        return name;
    }

    private static String convertTableToClass2(String content) {
        String name = "";
        if (content.contains("_")) {
            //前后拼接
            String[] names = content.split("_");
            for (int i = 0; i < names.length; i++) {
                String tempName = names[i];
                if(i==0){
                    tempName = tempName.substring(0, 1).toLowerCase() + tempName.substring(1);
                }else {
                    tempName = tempName.substring(0, 1).toUpperCase() + tempName.substring(1);
                }
                name += tempName;

            }
        } else {
            name = content.substring(0, 1).toLowerCase() + content.substring(1);
        }
        return name;
    }
    public static Table generateTable(String tableName) {

//
        String sql = getSQL(tableName);
        Connection conn = null;
        Statement statment = null;
        Table table = new Table();
        table.setName(tableName);
        List<Column> columns = new ArrayList<>();
        try {
            // 1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2.建立连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/platAdminFrame?useUnicode=true&characterEncoding=UTF-8", "root", "");
            // 3.创建statment
            statment = conn.createStatement();
            // 4 执行指令
            ResultSet rs = statment.executeQuery(sql);

            while (rs.next()) {
//                if (!rs.getString(2).toLowerCase().equals("id")) {
                Column column = new Column();
                column.setName(convertTableToClass2(rs.getString(1)));
                column.setColumn(rs.getString(1));
                column.setType(convertType(rs.getString(2)));
                if(rs.getString(5)!=null&&!"".equals(rs.getString(5))){
                    column.setDescription(rs.getString(5).split(",")[0]);
                }else{
                    column.setDescription(convertTableToClass(rs.getString(1)));
                }
                columns.add(column);
//                }
                //System.out.println(rs.getString(1)+"------"+rs.getString(2));
            }
            table.setColumns(columns);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return table;
    }

    private static String convertType(String content) {
        switch (content) {
            case "varchar":
                return "String";
            case "int":
                return "Integer";
            case "float":
                return "double";
            case "decimal":
                return "double";
            case "datetime":
                return "Date";
        }
        return "String";
    }


    public static String getSQL(String tableName) {
        String sql = "select a.column_name 'name',a.data_type 'type'," +
                "a.CHARACTER_MAXIMUM_LENGTH 'length',a.COLUMN_DEFAULT 'defaultValue', " +
                "a.COLUMN_COMMENT 'description' from information_schema.columns a where table_name='" + tableName + "'";
        return sql;
    }

}
